package com.netease.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;

@Api(value = "文件相关接口", tags = {"文件相关接口"})
@Controller
@Slf4j
public class FileController {
    private final String FILE_PATH = "/root" + File.separator +"dataElement.csv";

    private final static String utf8 ="utf-8";

    @ApiOperation(value = "文件下载", notes = "文件下载", httpMethod = "POST")
    @RequestMapping("/download")
    public void downLoadFile(HttpServletRequest request, HttpServletResponse response) throws Exception {
        File file = new File(FILE_PATH);
        if (file.exists()){
            response.setCharacterEncoding(utf8);
            InputStream is = null;
            OutputStream os = null;
            try{
                //分片下载   http  Range bytes=100-1000   bytes=100-
                long fSize = file.length();
                response.setContentType("application/x-download");
                String fileName = URLEncoder.encode(file.getName(),utf8);
                response.addHeader("Content-Disposition","attachment;filename=" + fileName);
                response.setHeader("Accept-Range","bytes");

                response.setHeader("fSize",String.valueOf(fSize));
                response.setHeader("fName",fileName);

                long pos = 0,last = fSize-1,sum = 0;
                if(null != request.getHeader("Range")){
                    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);

                    String numRange = request.getHeader("Range").replaceAll("bytes=","");
                    String[] strRange = numRange.split("-");
                    if(strRange.length == 2){
                        pos = Long.parseLong(strRange[0].trim());
                        last = Long.parseLong(strRange[1].trim());
                        if(last > fSize-1){
                            last = fSize-1;
                        }
                    }else{
                        pos = Long.parseLong(numRange.replaceAll("-","").trim());
                    }
                }
                long rangeLenght = last - pos +1;
                String contentRange = new StringBuffer("bytes ").append(pos).append("-").append(last).append("/").append(fSize).toString();
                response.setHeader("Content-Range",contentRange);
                response.setHeader("Content-Lenght",String.valueOf(rangeLenght));

                os = new BufferedOutputStream(response.getOutputStream());
                is = new BufferedInputStream(new FileInputStream(file));
                is.skip(pos);
                byte[] buffer = new byte[1024];
                int lenght = 0;
                while(sum < rangeLenght){
                    lenght = is.read(buffer,0,((rangeLenght-sum) <= buffer.length ? ((int)(rangeLenght-sum)) :  buffer.length));
                    sum = sum+ lenght;
                    os.write(buffer,0,lenght);
                }
                System.out.println("下载完成");
            }finally {
                if(is != null){
                    is.close();
                }
                if(os != null){
                    os.close();
                }
            }
        }else {
            log.info("你要下载的文件不存在！");
        }
    }

    @ApiOperation(value = "文件上传", notes = "文件上传", httpMethod = "POST")
    @RequestMapping("/upload")
    @ResponseBody
    public void upload(HttpServletRequest request, HttpServletResponse response) throws Exception {

        //分片
        response.setCharacterEncoding(utf8);
        Integer schunk = null;
        Integer schunks = null;
        String name = null;
        String uploadPath = "/Users/aochong/fileItem";
        BufferedOutputStream os = null;
        try{
            DiskFileItemFactory factory = new DiskFileItemFactory();
            factory.setSizeThreshold(1024);
            factory.setRepository(new File(uploadPath));
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setFileSizeMax(5l *1024l *1024l*1024l);
            upload.setSizeMax(10l *1024l *1024l*1024l);
            List<FileItem> items = upload.parseRequest(request);

            for(FileItem item : items){
                if(item.isFormField()){
                    if("chunk".equals(item.getFieldName())){
                        schunk = Integer.parseInt(item.getString(utf8));
                    }
                    if("chunks".equals(item.getFieldName())){
                        schunks = Integer.parseInt(item.getString(utf8));
                    }
                    if("name".equals(item.getFieldName())){
                        name = item.getString(utf8);
                    }
                }
            }
            for(FileItem item : items){
                if(!item.isFormField()){
                    String temFileName = name;
                    if(name != null){
                        if(schunk != null){
                            temFileName = schunk +"_"+name;
                        }
                        File temFile = new File(uploadPath,temFileName);
                        //断点续传
                        if(!temFile.exists()){
                            item.write(temFile);
                        }
                    }
                }
            }
            //文件合并
            if(schunk != null && schunk.intValue() == schunks.intValue()-1){
                File tempFile = new File(uploadPath,name);
                os = new BufferedOutputStream(new FileOutputStream(tempFile));

                for(int i=0 ;i<schunks;i++){
                    File file = new File(uploadPath,i+"_"+name);
                    while(!file.exists()){
                        Thread.sleep(100);
                    }
                    byte[] bytes = FileUtils.readFileToByteArray(file);
                    os.write(bytes);
                    os.flush();
                    file.delete();
                }
                os.flush();
            }
            response.getWriter().write("上传成功"+name);
        }finally {
            try{
                if(os != null){
                    os.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}
